package com.ihr360.job.core.repository.dao;

import com.ihr360.job.core.JobParameters;
import com.ihr360.job.core.entity.JobExecution;
import com.ihr360.job.core.entity.JobInstance;
import com.ihr360.job.core.lanuch.NoSuchJobException;

import java.util.List;

/**
 * Data Access Object for job instances.
 *
 * @author Lucas Ward
 * @author Robert Kasanicky
 * @author Michael Minella
 *
 */
public interface JobInstanceDao {

    /**
     * Create a JobInstance with given name and parameters.
     *
     * PreConditions: JobInstance for given name and parameters must not already
     * exist
     *
     * PostConditions: A valid job instance will be returned which has been
     * persisted and contains an unique Id.
     *
     * @param jobName
     * @param jobParameters
     * @return JobInstance
     */
    JobInstance createJobInstance(String jobName, JobParameters jobParameters);

    /**
     * Find the job instance that matches the given name and parameters. If no
     * matching job instances are found, then returns null.
     *
     * @param jobName the name of the job
     * @param jobParameters the parameters with which the job was executed
     * @return {@link JobInstance} object matching the job name and
     * {@link JobParameters} or null
     */
    JobInstance getJobInstance(String jobName, JobParameters jobParameters);

    /**
     * Fetch the job instance with the provided identifier.
     *
     * @param instanceId the job identifier
     * @return the job instance with this identifier or null if it doesn't exist
     */
    JobInstance getJobInstance(Long instanceId);

    /**
     * Fetch the JobInstance for the provided JobExecution.
     *
     * @param jobExecution the JobExecution
     * @return the JobInstance for the provided execution or null if it doesn't exist.
     */
    JobInstance getJobInstance(JobExecution jobExecution);

    /**
     * Fetch the last job instances with the provided name, sorted backwards by
     * primary key.
     *
     * if using the JdbcJobInstance, you can provide the jobName with a wildcard
     * (e.g. *Job) to return 'like' job names. (e.g. *Job will return 'someJob'
     * and 'otherJob')
     *
     * @param jobName the job name
     * @param start the start index of the instances to return
     * @param count the maximum number of objects to return
     * @return the job instances with this name or empty if none
     */
    List<JobInstance> getJobInstances(String jobName, int start, int count);

    /**
     * Retrieve the names of all job instances sorted alphabetically - i.e. jobs
     * that have ever been executed.
     * @return the names of all job instances
     */
    List<String> getJobNames();

    /**
     * Fetch the last job instances with the provided name, sorted backwards by
     * primary key, using a 'like' criteria
     *
     * @param jobName
     * @param start
     * @param count
     * @return
     */
    List<JobInstance> findJobInstancesByName(String jobName, int start, int count);


    /**
     * Query the repository for the number of unique {@link JobInstance}s
     * associated with the supplied job name.
     *
     * @param jobName the name of the job to query for
     * @return the number of {@link JobInstance}s that exist within the
     * associated job repository
     * @throws NoSuchJobException
     */
    int getJobInstanceCount(String jobName) throws NoSuchJobException;

}
